package me.magicall.myblog.base.web.springmvc.interceptors;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.magicall.myblog.util.ModelEnumHolder;
import me.magicall.myblog.util.UrlPatternRule.UrlPatternPart;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

public class SecurityCheckInterceptor implements HandlerInterceptor, Ordered {

	private static final Map<Pattern, Integer> PATTERN_MODEL_NAME_GROUP_INDEX = new HashMap<Pattern, Integer>();
	static {
		PATTERN_MODEL_NAME_GROUP_INDEX.put(Pattern.compile("^/(\\w|\\d|-)+/(" + UrlPatternPart.MODEL_NAME.regex + ")/?.*$"), 2);
//		PATTERN_MODEL_NAME_GROUP_INDEX.put(Pattern.compile("^/(\\w|\\d)+/admin/(" + UrlPatternPart.MODEL_NAME.regex + ")/.*$"), 2);
	}
	@Autowired
	private ModelEnumHolder modelEnumHolder;

	@Override
	public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex)
			throws Exception {
	}

	@Override
	public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView)
			throws Exception {
	}

	@Override
	public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
		if (handler instanceof ResourceHttpRequestHandler) {
			return true;
		}
		final String uri = request.getRequestURI();
		//uri not right
		Matcher matcher = null;
		int modelNameGroupIndex = 0;
		for (final Entry<Pattern, Integer> e : PATTERN_MODEL_NAME_GROUP_INDEX.entrySet()) {
			final Pattern pattern = e.getKey();
			matcher = pattern.matcher(uri);
			if (matcher.matches()) {
				modelNameGroupIndex = e.getValue();
				break;
			}
		}
		if (matcher == null) {
			return forbidden(response);
		}

		//no such model
		if (matcher.groupCount() < modelNameGroupIndex) {
			return forbidden(response);
		}
		try {
			final String modelName = matcher.group(modelNameGroupIndex);
			final Class<? extends Enum<?>> enumClass = modelEnumHolder.getEnumClass(modelName);
			if (enumClass == null) {
				return forbidden(response);
			} else {
				request.setAttribute("fields", enumClass.getEnumConstants());
			}
			return true;
		} catch (final IllegalStateException e) {
			e.printStackTrace();
			return forbidden(response);
		}
	}

	/**
	 * @param response
	 */
	private boolean forbidden(final HttpServletResponse response) {
		response.setStatus(HttpStatus.FORBIDDEN.value());
		return false;
	}

	@Override
	public int getOrder() {
		return Ordered.HIGHEST_PRECEDENCE;
	}

}
